/**
 * 安卓白金英雄坛制作组 <br>
 * 文件名：MapScreen.java <br>
 * 创建时间：2013-5-20 下午4:52:07 <br>
 * 所属项目：GmudEX <br>
 * @author 12548 <br>
 */
package lostland.gmud.exv2;

import static lostland.gmud.exv2.Gmud.StringLength;
import static lostland.gmud.exv2.Gmud.getBgColor;
import static lostland.gmud.exv2.Gmud.getCalString;
import static lostland.gmud.exv2.Gmud.getNpc;
import static lostland.gmud.exv2.Gmud.maps;
import static lostland.gmud.exv2.Gmud.mc;
import lostland.gmud.exv2.blgframework.BasicScreen;
import lostland.gmud.exv2.blgframework.CScreen;
import lostland.gmud.exv2.blgframework.impl.BLGGraphics;
import lostland.gmud.exv2.data.FlyPoint;
import lostland.gmud.exv2.data.GmudMap;
import lostland.gmud.exv2.data.IngameData;
import lostland.gmud.exv2.data.Npc;
import lostland.gmud.exv2.data.NpcModifier;
import lostland.gmud.exv2.data.Room;
import lostland.gmud.exv2.expand.FlyingScreen;
import lostland.gmud.exv2.graphics.MapBuffer;
import lostland.gmud.exv2.js.JsCommon;
import lostland.gmud.exv2.ui.MainMenuScreen;
import lostland.gmud.exv2.ui.NpcMenuScreen;
import lostland.gmud.exv2.ui.core.ButtonControlledScreen;
import lostland.gmud.exv2.ui.core.NewButton;

/**
 * 类名：MapScreen <br>
 * 说明：在地图上的主界面。
 *
 * @author 12548
 */
public class MapScreen extends ButtonControlledScreen {

	public static int C_COLUMNS = 9;
	public static int C_ROWS = 15;

	public static final int WS_INNER = 1;
	public static final int WS_OUTSIDE = 2;

	public static FlyPoint npcPlace = null;

	private static boolean b = false;

	private float tickTime = 0.0f;
	public static boolean walking = false;
	public static int walkStep, walkState;
	public static int X, Y;
	public static int mapid;

	public int round = 0, number = 0;
	public MapBuffer mb;

	public static final float STEP_TIME[] = {0.058f, 0.047f, 0.03f};

	//	public Bitmap bmp;
	//	public SparseBooleanArray cached = new SparseBooleanArray();

	/**
	 * @return ms
	 */
	public static MapScreen getInstance() {
		for (CScreen i : Game.getInstance().scene) {
			if (i instanceof MapScreen) {
				ms = (MapScreen) i;
			}
		}

		if (ms == null) {
			ms = new MapScreen();
		}
		return ms;
	}


	/**
	 * @param ms 要设置的 ms
	 */
	public static void setMs(MapScreen ms) {
		MapScreen.ms = ms;
	}


	/**
	 * @return map
	 */
	public GmudMap getMap() {
		return maps[mapid];
	}

	int bgmid = 0;

	private static MapScreen ms;


	/**
	 * @param map 要设置的 map
	 */
	public void setMap(GmudMap map) {
		if (mapid != map.id) {
			initMap(map);
		}
		mapid = map.id;
		if (Assets.bgm_map.get(map.id) != null) {
			bgmid = map.id;
		}
	}


	public void initMap(GmudMap map) {

		//		cached.clear();
		//		Bitmap bmp = Bitmap.createBitmap(map.width * 32, map.height * 32, Config.ARGB_8888);
		//
		//		bmp.eraseColor(Gmud.getBgColor());
		//		updateMapBmp(map, bmp);
		//
		//		this.bmp = bmp;
	}


	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.blgframework.CScreen#update(float)
	 */
	@Override
	public void update(float deltaTime) {
		super.update(deltaTime);

		if (!isB()) {
			setB(true);
		}
		BasicScreen.setTimeFlowing(true);


		if (walking) {
			tickTime += deltaTime;
			if (tickTime > STEP_TIME[Game.resolution_level]) {
				tickTime -= STEP_TIME[Game.resolution_level];
				walkStep++;
				MainCharTile.getInstance().currentStep = (MainCharTile.getInstance().currentStep + 1) % 4;
				if (walkStep >= MainCharTile.WALK_STEPS) {
					if (walkState == WS_INNER) {
						MainCharTile.getInstance().X += MainCharTile.getInstance().currentDirection.dx();
						MainCharTile.getInstance().Y += MainCharTile.getInstance().currentDirection.dy();
					} else {
						X += MainCharTile.getInstance().currentDirection.dx();
						Y += MainCharTile.getInstance().currentDirection.dy();
					}

					if (getMap().getEvent(MainCharTile.absX(), MainCharTile.absY()) > -1) {
						int t = getMap().getEvent(MainCharTile.absX(), MainCharTile.absY());
						int i_map = t / 1000000;
						t %= 1000000;
						int i_x = t / 1000;
						int i_y = t % 1000;
						jumpTo(i_map, i_x, i_y, MainCharTile.getInstance().currentDirection);
						if (Game.autoAddFlyPoint) {
							getGame().data.addfp(i_map, i_x, i_y, MainCharTile.getInstance().currentDirection);
						}
					}

					walkStep = 0;
					if (continue_walking()) {
						walkProcess();
					} else {
						walking = false;
					}
				}
			}
		} else {
			if (nbDetect()) return;
			timeCheck();

		}
	}


	/**
	 *
	 */
	public static void timeCheck() {
		while (Game.getInstance().data.hour >= GameConstants.SECONDS_PER_DAY) {
			mc.day++;
			Game.getInstance().data.yellowcal = Gmud.rand.nextInt(16);
			Game.getInstance().data.hour -= GameConstants.SECONDS_PER_DAY;

			if (IngameData.getInstance().nextBadman > 0) {
				IngameData.getInstance().nextBadman = 0;
			}

			if (IngameData.getInstance().nextNiceguy > 0) {
				IngameData.getInstance().nextNiceguy = 0;
			}

		}

		while (mc.day >= 30) {
			mc.day -= 30;
			mc.month++;
		}

		while (mc.month >= 12) {
			mc.month -= 12;
			mc.age++;
			Game.getInstance().data.tournament_finished = !(mc.age % 4 == 0);
		}

		while (Game.getInstance().data.hungerTime >= 15.0) {
			Game.getInstance().data.hungerTime -= 15.0;
			mc.food--;
			mc.drink--;
			if (mc.food < 0) {
				mc.food = 0;
			}
			if (mc.drink < 0) {
				mc.drink = 0;
			}

			if (mc.food > 0 && mc.drink > 0) {
				mc.setHp((int) (mc.getHp() + mc.getAttr(Room.ATTR_MAXHP) * 0.01));
				if(mc.getHp() > mc.getAttr(Room.ATTR_MAXHP)) {
					mc.setHp(mc.getAttr(Room.ATTR_MAXHP));
				}
				mc.rec(mc.getAttr(Room.ATTR_BON) / 2);
			}
		}
	}


	/**
	 * 角色瞬间移动到指定位置
	 *
	 * @param mapid 地图id
	 * @param x     x坐标
	 * @param y     y坐标
	 * @param d     角色方向
	 */
	public void jumpTo(int mapid, int x, int y, Direction d) {
		setMap(maps[mapid]);

		//		switch(d)
		//		{
		//		case DOWN:
		//			if(MainCharTile.getInstance().Y >= C_COLUMNS-2){
		//				MainCharTile.getInstance().X = (C_ROWS+1)/2;
		//				MainCharTile.getInstance().Y = (C_COLUMNS+1)/2;
		//			}
		//			break;
		//		case LEFT:
		//			if(MainCharTile.getInstance().X <= 1){
		//				MainCharTile.getInstance().X = (C_ROWS+1)/2;
		//				MainCharTile.getInstance().Y = (C_COLUMNS+1)/2;
		//			}
		//			break;
		//		case RIGHT:
		//			if(MainCharTile.getInstance().X >= C_ROWS-2){
		//				MainCharTile.getInstance().X = (C_ROWS+1)/2;
		//				MainCharTile.getInstance().Y = (C_COLUMNS+1)/2;
		//			}
		//			break;
		//		case UP:
		//			if(MainCharTile.getInstance().Y <= 1){
		//				MainCharTile.getInstance().X = (C_ROWS+1)/2;
		//				MainCharTile.getInstance().Y = (C_COLUMNS+1)/2;
		//			}
		//			break;
		//		default:
		//			break;
		//
		//		}


		if (getMap().width <= C_ROWS) {
			MainCharTile.getInstance().X = (C_ROWS + 1) / 2;
		}

		if (getMap().height <= C_COLUMNS) {
			MainCharTile.getInstance().Y = (C_COLUMNS + 1) / 2;
		}

		if (MainCharTile.getInstance().Y >= C_COLUMNS - 2 ||
				MainCharTile.getInstance().X <= 1 ||
				MainCharTile.getInstance().X >= C_ROWS - 2 ||
				MainCharTile.getInstance().Y <= 1
				) {
			MainCharTile.getInstance().X = (C_ROWS + 1) / 2;
			MainCharTile.getInstance().Y = (C_COLUMNS + 1) / 2;
		}


		X = x - MainCharTile.getInstance().X;
		Y = y - MainCharTile.getInstance().Y;

		MainCharTile.getInstance().currentDirection = d;

		if (getMap().width >= C_ROWS) {
			if (X < 0) {
				int tt = -X;
				X = 0;
				MainCharTile.getInstance().X -= tt;
			}
			if (X + C_ROWS >= getMap().width) {
				int tt = X + C_ROWS - getMap().width;
				X -= tt;
				MainCharTile.getInstance().X += tt;
			}

		}

		if (getMap().height >= C_COLUMNS) {
			if (Y < 0) {
				int tt = -Y;
				Y = 0;
				MainCharTile.getInstance().Y -= tt;
			}
			if (Y + C_COLUMNS > getMap().height) {
				int tt = Y + C_COLUMNS - getMap().height;
				Y -= tt;
				MainCharTile.getInstance().Y += tt;
			}

		}


		if (X < 0 && MainCharTile.getInstance().currentDirection == Direction.RIGHT) {
			int tt = -X;
			X = 0;
			MainCharTile.getInstance().X -= tt;
		}

		if (Y < 0 && MainCharTile.getInstance().currentDirection == Direction.DOWN) {
			int tt = -Y;
			Y = 0;
			MainCharTile.getInstance().Y -= tt;
		}

		//		if(getMap().width < 10)
		//		{
		//			int tt = -X;
		//			X = 0;
		//			MainCharTile.getInstance().X-=tt;
		//		}


		getGame().changeBGM(Assets.bgm_map.get(bgmid));
	}


	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.blgframework.CScreen#pause()
	 */
	@Override
	public void pause() {
		setB(false);
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.blgframework.CScreen#resume()
	 */
	@Override
	public void resume() {
		MapScreen.setMs(this);
		super.resume();

		getGame().changeBGM(Assets.bgm_map.get(bgmid));
		getGame().getBGM().setLooping(true);
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.blgframework.CScreen#dispose()
	 */
	@Override
	public void dispose() {

	}

	boolean continue_walking() {
		if (isDown) {
			switch (NewButton.inbound(otx, oty)) {
			case NB_DOWN:
				MainCharTile.getInstance().currentDirection = Direction.DOWN;
				break;
			case NB_LEFT:
				MainCharTile.getInstance().currentDirection = Direction.LEFT;
				break;
			case NB_RIGHT:
				MainCharTile.getInstance().currentDirection = Direction.RIGHT;
				break;
			case NB_UP:
				MainCharTile.getInstance().currentDirection = Direction.UP;
				break;
			default:
				return false;
			}

			if (getMap().isWalkable(X + MainCharTile.getInstance().X + MainCharTile.getInstance().currentDirection.dx(),
					Y + MainCharTile.getInstance().Y + MainCharTile.getInstance().currentDirection.dy()))
				return true;

		}
		return false;
	}


	boolean nbDetect() {
		if (isDown) {
			switch (NewButton.inbound(otx, oty)) {
			case NB_DOWN:
				MainCharTile.getInstance().currentDirection = Direction.DOWN;
				if (getMap().isWalkable(X + MainCharTile.getInstance().X + MainCharTile.getInstance().currentDirection.dx(),
						Y + MainCharTile.getInstance().Y + MainCharTile.getInstance().currentDirection.dy())) {
					walkProcess();
					return true;
				}
				break;
			case NB_LEFT:
				MainCharTile.getInstance().currentDirection = Direction.LEFT;
				if (getMap().isWalkable(X + MainCharTile.getInstance().X + MainCharTile.getInstance().currentDirection.dx(),
						Y + MainCharTile.getInstance().Y + MainCharTile.getInstance().currentDirection.dy())) {
					walkProcess();
					return true;
				}
				break;
			case NB_RIGHT:
				MainCharTile.getInstance().currentDirection = Direction.RIGHT;
				if (getMap().isWalkable(X + MainCharTile.getInstance().X + MainCharTile.getInstance().currentDirection.dx(),
						Y + MainCharTile.getInstance().Y + MainCharTile.getInstance().currentDirection.dy())) {
					walkProcess();
					return true;
				}
				break;
			case NB_UP:
				MainCharTile.getInstance().currentDirection = Direction.UP;
				if (getMap().isWalkable(X + MainCharTile.getInstance().X + MainCharTile.getInstance().currentDirection.dx(),
						Y + MainCharTile.getInstance().Y + MainCharTile.getInstance().currentDirection.dy())) {
					walkProcess();
					return true;
				}
				break;
			default:
				break;
			}
		}
		return false;
	}

	void walkProcess() {
		if (
				(MainCharTile.getInstance().X < ((C_ROWS - 1) / 2) && MainCharTile.getInstance().currentDirection == Direction.RIGHT) ||
				(MainCharTile.getInstance().X > ((C_ROWS - 1) / 2) && MainCharTile.getInstance().currentDirection == Direction.LEFT) ||
				(MainCharTile.getInstance().Y < ((C_COLUMNS - 1) / 2) && MainCharTile.getInstance().currentDirection == Direction.DOWN) ||
				(MainCharTile.getInstance().Y > ((C_COLUMNS - 1) / 2) && MainCharTile.getInstance().currentDirection == Direction.UP) ||
				(X + C_ROWS >= getMap().width && MainCharTile.getInstance().currentDirection == Direction.RIGHT) ||
				(X <= 0 && MainCharTile.getInstance().currentDirection == Direction.LEFT) ||
				(Y + C_COLUMNS >= getMap().height && MainCharTile.getInstance().currentDirection == Direction.DOWN) ||
				(Y <= 0 && MainCharTile.getInstance().currentDirection == Direction.UP)
				) {
			walkState = WS_INNER;
		} else {
			walkState = WS_OUTSIDE;
		}
		walking = true;
	}

	void eventProcess(int eventid) {
		GameEvent.callEvent(eventid);
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.ui.core.ButtonControlledScreen#onButtonDown(lostland.gmud.exv2.ui.core.NewButton)
	 */
	@Override
	protected void onButtonDown(NewButton b) {
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.ui.core.ButtonControlledScreen#onButtonClick(lostland.gmud.exv2.ui.core.NewButton)
	 */
	@Override
	public void onButtonClick(NewButton b) {

		if (!walking) {
			switch (b) {
			case NB_BACK:
				MainMenuScreen.getInstance().pushToGame();
				break;
			case NB_DOWN:
				break;
			case NB_ENTER:
				int npcid = getMap().getEvent(MainCharTile.frontAbsX(), MainCharTile.frontAbsY());
				npcPlace = new FlyPoint(mapid, MainCharTile.frontAbsX(), MainCharTile.frontAbsY());
				if (getMap().getWalkable(MainCharTile.frontAbsX(), MainCharTile.frontAbsY()) == GmudMap.MP_NPC) {
					if (!getGame().data.death_note.contains(npcid) && !getGame().data.vanish_note.contains(npcid)) {
						Npc npc = getNpc().get(npcid);
						if (npc.haveFlag(Npc.FLAG_BADMAN)) {
							npc.badman(true);
							NpcModifier.TEMPLATE_BADMAN.applyTo(npc, (0.8f + (round + number) * 0.05f));
//								getNpc().get(npcid).setDifficulty(0.8f + (round + number) * 0.05f);
						} else if (npc.haveFlag(Npc.FLAG_NICEGUY)) {
							npc.badman(false);
							NpcModifier.TEMPLATE_NICEGUY.applyTo(npc, (0.8f + (round + number) * 0.05f));
//								getNpc().get(npcid).setDifficulty(0.8f + (round + number) * 0.05f);
						}
						new NpcMenuScreen(npcid).pushToGame();
					} else {
						//Do nothing
					}
				} else if (getMap().getWalkable(MainCharTile.frontAbsX(), MainCharTile.frontAbsY()) == GmudMap.MP_EVENT) {
					eventProcess(npcid);
				} else if (getMap().getWalkable(MainCharTile.frontAbsX(), MainCharTile.frontAbsY()) == GmudMap.MP_SIMPLESCRIPT) {
					JsCommon.prepareScriptToExec(JsCommon.getSimpleScripts(npcid));
					JsCommon.execScriptOver();
				}
				break;
			case NB_LEFT:
				break;
			case NB_RIGHT:
				break;
			case NB_UP:
				break;
			case NB_MENU:
				if (Game.menuKeyForFly) {
					FlyingScreen.fly();
				} else {
					MainMenuScreen.getInstance().pushToGame();
				}
				break;
			default:
				break;

			}
		}
	}

	/* （非 Javadoc）
	 * @see lostland.gmud.exv2.ui.core.ButtonControlledScreen#show()
	 */
	@Override
	protected void show() {
		//		rTime+=deltaTime;
		//		if(rTime<1.0f)
		//			fCount++;
		//		else{
		//			fps=fCount;
		//			fCount=0;
		//			rTime-=1.0;
		//		}
		BLGGraphics g = (BLGGraphics) getGame().getGraphics();
		//		g.clear(GameConstants.BG_COLOR);


		if ((!walking) || walkState == WS_INNER) {
			getMap().draw(MapTile.getInstance(), X, Y);
//			MapBuffer.getInstance().bufferMap(0, 0);
		} else {
//			MapBuffer.getInstance().bufferMap( MapTile.TILE_WIDTH * MainCharTile.getInstance().currentDirection.inverse().dx() * walkStep / MainCharTile.WALK_STEPS, MapTile.TILE_WIDTH * MainCharTile.getInstance().currentDirection.inverse().dy() * walkStep / MainCharTile.WALK_STEPS);

			getMap().drawWalking(MapTile.getInstance(), X, Y, MapTile.TILE_WIDTH * MainCharTile.getInstance().currentDirection.inverse().dx() * walkStep / MainCharTile.WALK_STEPS, MapTile.TILE_WIDTH * MainCharTile.getInstance().currentDirection.inverse().dy() * walkStep / MainCharTile.WALK_STEPS);
		}

		if (walking)
			if (walkState == WS_INNER) {
				MainCharTile.getInstance().drawInnerWalking(MainCharTile.getInstance().currentDirection, walkStep, MainCharTile.getInstance().X, MainCharTile.getInstance().Y);
			} else {
				MainCharTile.getInstance().drawOriWalking(MainCharTile.getInstance().currentDirection, MainCharTile.getInstance().X, MainCharTile.getInstance().Y);
			}
		else {
			MainCharTile.getInstance().drawInMap(MainCharTile.getInstance().currentDirection, MainCharTile.getInstance().currentStep, MainCharTile.getInstance().X, MainCharTile.getInstance().Y);
		}

		if (isB()) {
			String s = getMap().getName();
			g.drawRect(0, 0, s.length() * 12, 12, getBgColor());
			g.drawText(s, 0, 0, FontSize.FT_12PX);
		}

		if (mc.equips(92)) {
			String abs = MainCharTile.absX() + "," + MainCharTile.absY();
			g.drawRect(0, 12, abs.length() * 6, 12, Gmud.getBgColor());
			g.drawText(abs, 0, 12, FontSize.FT_12PX);
		}


		if (mc.equips(91)) {
			String s = getCalString();
			int len = StringLength(s);
			g.drawRect(GameConstants.FBWIDTH - len, 0, len, 12, getBgColor());
			g.drawText(s, GameConstants.FBWIDTH - len, 0, FontSize.FT_12PX);
		}

		/*
		int len = GmudWorld.StringLength(w);
		g.drawRect(GameConstants.FBWIDTH - len, 12, len, 12, GameConstants.BG_COLOR);
		g.drawText(w, GameConstants.FBWIDTH - len, 12, FontSize.FT_12PX);
		if(btnsEnabled){
			btnUp.draw();
			btnDown.draw();
			btnLeft.draw();
			btnRight.draw();
			btnEnter.draw();
			btnMenu.draw();
		}*/
	}


	/**
	 * 判断是否相邻
	 *
	 * @param x1 横坐标1
	 * @param y1 纵坐标1
	 * @param x2 横坐标2
	 * @param y2 纵坐标2
	 * @return
	 */
	public static boolean near(int x1, int y1, int x2, int y2) {
		return Math.abs(x1 - x2) + Math.abs(y1 - y2) == 1;
	}


	public static boolean isB() {
		return b;
	}


	public static void setB(boolean b) {
		MapScreen.b = b;
	}

}
